﻿using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace Labthink.PCSoft.UniversalHost4.UserControls
{
    public partial class MarqueeText
    {
        private Size _contentSize;
        MarqueeType _marqueeType;

        public MarqueeType MarqueeType
        {
            get => _marqueeType;
            set => _marqueeType = value;
        }

        public string MarqueeContent
        {
            set
            {
                tbmarquee.Text = value;
                _contentSize = GetTextDisplayWidth(value, tbmarquee.FontFamily, tbmarquee.FontStyle,
                    tbmarquee.FontWeight, tbmarquee.FontStretch, tbmarquee.FontSize);
            }
        }

        private double _marqueeTimeInSeconds;

        public double MarqueeTimeInSeconds
        {
            get => _marqueeTimeInSeconds;
            set => _marqueeTimeInSeconds = value;
        }


        public MarqueeText()
        {
            InitializeComponent();
            canMain.Height = this.Height;
            canMain.Width = this.Width;
            this.Loaded += MarqueeText_Loaded;
        }

        void MarqueeText_Loaded(object sender, RoutedEventArgs e)
        {
            StartMarqueeing(_marqueeType);
        }

        public void StartMarqueeing(MarqueeType marqueeType)
        {
            if (marqueeType == MarqueeType.LeftToRight)
            {
                LeftToRightMarquee();
            }
            else if (marqueeType == MarqueeType.RightToLeft)
            {
                RightToLeftMarquee();
            }
            else if (marqueeType == MarqueeType.TopToBottom)
            {
                TopToBottomMarquee();
            }
            else if (marqueeType == MarqueeType.BottomToTop)
            {
                BottomToTopMarquee();
            }
        }

        private void LeftToRightMarquee()
        {
            double height = canMain.ActualHeight - _contentSize.Height;
            tbmarquee.Margin = new Thickness(0, height / 2, 0, 0);
            var doubleAnimation = new DoubleAnimation
            {
                From = -tbmarquee.ActualWidth,
                To = canMain.ActualWidth,
                RepeatBehavior = RepeatBehavior.Forever,
                Duration = new Duration(TimeSpan.FromSeconds(_marqueeTimeInSeconds))
            };

            tbmarquee.BeginAnimation(Canvas.LeftProperty, doubleAnimation);
        }

        private void RightToLeftMarquee()
        {
            double height = canMain.ActualHeight - _contentSize.Height;
            tbmarquee.Margin = new Thickness(0, height / 2, 0, 0);
            var doubleAnimation = new DoubleAnimation
            {
                From = -tbmarquee.ActualWidth,
                To = canMain.ActualWidth,
                RepeatBehavior = RepeatBehavior.Forever,
                Duration = new Duration(TimeSpan.FromSeconds(_marqueeTimeInSeconds))
            };

            tbmarquee.BeginAnimation(Canvas.RightProperty, doubleAnimation);
        }

        private void TopToBottomMarquee()
        {
            double width = canMain.ActualWidth - tbmarquee.ActualWidth;
            tbmarquee.Margin = new Thickness(width / 2, 0, 0, 0);
            var doubleAnimation = new DoubleAnimation
            {
                From = -tbmarquee.ActualHeight,
                To = canMain.ActualHeight,
                RepeatBehavior = RepeatBehavior.Forever,
                Duration = new Duration(TimeSpan.FromSeconds(_marqueeTimeInSeconds))
            };

            tbmarquee.BeginAnimation(Canvas.TopProperty, doubleAnimation);
        }
        private void BottomToTopMarquee()
        {
            double width = canMain.ActualWidth - tbmarquee.ActualWidth;
            tbmarquee.Margin = new Thickness(width / 2, 0, 0, 0);
            var doubleAnimation = new DoubleAnimation
            {
                From = -tbmarquee.ActualHeight,
                To = canMain.ActualHeight,
                RepeatBehavior = RepeatBehavior.Forever,
                Duration = new Duration(TimeSpan.FromSeconds(_marqueeTimeInSeconds))
            };

            tbmarquee.BeginAnimation(Canvas.BottomProperty, doubleAnimation);
        }

        public Size GetTextDisplayWidth(string str, FontFamily fontFamily, FontStyle fontStyle, FontWeight fontWeight, FontStretch fontStretch, double FontSize)
        {
            var pixelsPerDip = VisualTreeHelper.GetDpi(this).PixelsPerDip;
            var formattedText = new FormattedText(
                str,
                CultureInfo.CurrentUICulture,
                FlowDirection.LeftToRight,
                new Typeface(fontFamily, fontStyle, fontWeight, fontStretch),
                FontSize,
                Brushes.Black,
                pixelsPerDip
            );
           
            return new Size(formattedText.Width, formattedText.Height);
        }
    }

    public enum MarqueeType
    {
        LeftToRight,
        RightToLeft,
        TopToBottom,
        BottomToTop
    }
}
